home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Libraries
/
CW GUSI 1.6.4
/
doc
/
pod
/
GUSI_Advanced.pod
next >
Wrap
Text File
|
1995-04-07
|
10KB
|
307 lines
=head1 Advanced techniques
This section discusses a few techniques that probably not
every user of C<GUSI> needs.
=head2 FSSpec routines
If you need to do complicated things with the Mac file system,
the normal C<GUSI> routines are probably not sufficient, but you still might
want to use the internal mechanism C<GUSI> uses. This mechanism is provided in
the header file C<TFileSpec.h>, which defines both C<C> and C<C++> interfaces.
In the following, the C<C++> member functions will be discussed and C<C> equivalents
will be mentioned where available.
C<OSErr TFileSpec::Error()> returns the last error provoked by a C<TFileSpec> member
function.
C<TFileSpec::TFileSpec(const FSSpec & spec, Boolean useAlias = false)> constructs
a C<TFileSpec> from an C<FSSpec> and resolves alias files unless C<useAlias> is C<true>.
(The C<useAlias> parameter is also present in the following routines, but will not
be shown anymore).
C<TFileSpec(short vRefNum, long parID, ConstStr31Param name)>
constructs a C<TFileSpec> from its components.
C<TFileSpec(short wd, ConstStr31Param name)> constructs
a C<TFileSpec> from a working directory reference number and a path component.
This routine is available to C<C> users as
C<OSErr WD2FSSpec(short wd, ConstStr31Param name, FSSpec * desc)>.
C<TFileSpec(const char * path)> constructs a
C<TFileSpec> from a full or relative path name.
This routine is available to C<C> users as
C<OSErr Path2FSSpec(const char * path, FSSpec * desc)>.
C<TFileSpec(OSType object, short vol = kOnSystemDisk, long dir = 0)> constructs
special C<TFileSpec>s, depending on C<object>.
This routine is available to C<C> users as
C<OSErr Special2FSSpec(OSType object, short vol, long dirID, FSSpec * desc)>.
All constants in C<Folders.h> acceptable
for C<FindFolder()> can be passed, e.g. the following:
=over 4
=item kSystemFolderType
The system folder.
=item kDesktopFolderType
The desktop folder; objects in this folder show on the desk top.
=item kExtensionFolderType
Finder extensions go here.
=item kPreferencesFolderType
Preferences for applications go here.
=back
Furthermore, the value C<kTempFileType> is defined, which creates a temporary
file in the temporary folder, or, if C<dir> is nonzero, in the directory you
specify.
C<TFileSpec(short fRefNum)> constructs a C<TFileSpec> from the file reference
number of an open file.
In principle, a C<TFileSpec> should be compatible with an C<FSSpec>. However, to
be absolutely sure, you can call C<TFileSpec::Bless()> which will call
C<FSMakeFSSpec()> before passing the TFileSpec to a C<FSp> file system routine.
C<char * TFileSpec::FullPath()> returns the full path name of the file. The
address returned points to a static buffer, so it will be overwritten on
further calls.
This routine is available to C<C> users as
C<char * FSp2FullPath(const FSSpec * desc)>.
C<char * TFileSpec::RelPath()> works like C<FullPath()>, but when the current
folder given by C<chdir()> is a pparent folder of the object, a relative path
name will be returned. The address returned points to a static buffer, so it
will be overwritten on further calls.
This routine is available to C<C> users as
C<char * FSp2RelPath(const FSSpec * desc)>.
C<char * TFileSpec::Encode()> returns an ASCII encoding which may be passed
to all C<GUSI> routines taking path names. The address returned points to a
static buffer, so it will be overwritten on further calls. This generates
short names which may be parsed rather quickly.
This routine is available to C<C> users as
C<char * FSp2Encoding(const FSSpec * desc)>.
C<OSErr TFileSpec::CatInfo(CInfoPBRec & info, Boolean dirInfo = false)> Gives
information about the current object. If C<dirInfo> is C<true>, gives information
about the current object's directory.
This routine is available to C<C> users as
C<OSErr FSpCatInfo(const FSSpec * desc, CInfoPBRec * info)>.
C<OSErr TFileSpec::Resolve(Boolean gently = true)> resolve the object if it is an alias file.
If gently is C<true> (the default), nonexisting files are tolerated.
C<Boolean TFileSpec::Exists()> returns C<true> if the object exists.
C<Boolean TFileSpec::IsParentOf(const TFileSpec & other)> returns C<true> if the object is
a parent of C<other>.
C<TFileSpec TFileSpec::operator--()> replaces the object with its parent directory.
This routine is available to C<C> users as
C<OSErr FSpUp(FSSpec * desc)>.
C<TFileSpec FileSpec::operator-=(int levels)> is equivalent to calling C<-->
C<levels> times and C<TFileSpec FileSpec::operator-(int levels)> is equivalent
to calling C<-=> on a I<copy> of the current object.
C<TFileSpec TFileSpec::operator+=(ConstStr31Param name)>,
C<TFileSpec TFileSpec::operator+=(const char * name)>, and their non-destructive
counterparts C<+> add a further component to the current object, which must be
an existing directory.
This routine is available to C<C> users as
C<OSErr FSpDown(FSSpec * desc, ConstStr31Param name)>.
C<TFileSpec TFileSpec::operator[](short index)> returns the C<index>th object in
the parent folder of the current object.
A destructive version of this routine is available to C<C> users as
C<OSErr FSpIndex(FSSpec * desc, short index)>.
Furthermore, the C<==> and C<!=> operators are defined to test C<TFileSpec>s for
equality.
C<OSErr FSpSmartMove(const FSSpec * from, const FSSpec * to)> does all the work
of moving and renaming a file (within the same volume), handling (I hope) all
special cases (You might be surprised how many there are).
=head2 File pattern iterators
Sometimes you might find it useful to find all files ending in C<.h> or all
directories starting with C<MW>. For this purpose, C<GUSI> offers a mechanism
in the header file C<TFileGlob.h>, which defines both C<C> and C<C++> interfaces.
You start a search by constructing a file pattern iterator with
C<TFileGlob::TFileGlob(const char * pattern, const TFileSpec * startDir = nil)>.
C<pattern> is an absolute or relative path name, with the following characters
getting a special interpretation:
=over 4
=item C<?>
Matches an arbitrary single character.
=item C<*>
Matches any number of characters (including none).
=item C<\>
Suppresses the special interpretation of the following character.
=back
C<startDir> provides a nonstandard starting directory for relative patterns.
After you have constructed the iterator, you can check whether a file was found
by calling C<Boolean TFileGlob::Valid()>. If one was found, you can use the
<TFileGlob> instance as a <TFileSpec> and thus as a <FSSpec>. To get the next
file, call C<Boolean TFileGlob::Next()>, which again returns C<true> if another
match was found.
To call the file pattern iterator routines from C<C>, you have the following
routines:
=over 4
=item C<FileGlobRef NewFileGlob(const char * pattern)>
Constructs an iterator.
=item C<Boolean NextFileGlob(FileGlobRef glob)>
Advances the iterator.
=item C<Boolean FileGlob2FSSpec(FileGlobRef glob, FSSpec * spec)>
Copies the file specification to C<spec> and returns whether the iterator is valid.
=item C<void DisposeFileGlob(FileGlobRef glob)>
Destructs the iterator.
=back
=head2 Adding your own socket families
It is rather easy to add your own socket
types to C<GUSI>:
=over 4
=item *
Pick an unused number between 17 and C<GUSI_MAX_DOMAINS> to use for your address family.
=item *
Include C<GUSI_P.h>.
=item *
Write a subclass of C<SocketDomain> and override C<socket()> and optionally C<choose()>.
=item *
Write a subclass of C<Socket> and override whatever you want. If you override
C<recvfrom()> and C<sendto()>, C<read()> and C<write()> are automatically defined.
=item *
For more information, study the code in C<GUSIDispatch.cp> and C<GUSISocket.cp>,
which implement the generic socket code. The easiest actual socket implementation
to study is probably C<GUSIUnix.cp>.
=back
=head2 Adding your own file families
C<GUSI> also supports adding special treatment for
certain file names to almost all (tell me if I have forgotten one) standard C<C> library
routines dealing with file names. To avoid countless rescanning of file names, C<GUSI>
preprocesses the names:
=over 4
=item *
If the file name starts with C<"Dev:"> (case insensitive), the file name is considered
a I<device name>, and the rest of the name can have any structure you like.
=item *
Otherwise, the name is translated into a C<FSSpec>, and therefore should refer to a real
file system object (all intermediate path name components should refer to existing
directories).
=back
To create a file family:
=over 4
=item *
Pick an address family, as described above. However, if you don't plan on creating sockets
of this family with socket(), just specify C<AF_UNSPEC>.
=item *
Include C<GUSIFile_P.h>.
=item *
Write a subclass of C<FileSocketDomain>, specifying whether you are interested in device
names, file names, or both, and override C<Yours()> and other calls.
=item *
Write a subclass of C<Socket> and override whatever you want.
=item *
For more information, study the code in C<GUSIFile.cp>, which implements the generic
file socket code.
=back
In your C<Yours()> member function, you specify whether you are prepared to handle
one of the following functions for a given file name:
enum Request {
willOpen,
willRemove,
willRename,
willGetFileInfo,
willSetFileInfo,
willFAccess,
willStat,
willChmod,
willUTime,
willAccess
};
If you return C<true> for a request, your corresponding member function will be called.
Member functions are similar to the corresponding C<C> library functions, except that
their first parameter is a C<GUSIFileRef &> instead of a C<const char *> (but further
file name parameters, as in C<rename()>, will be left untouched). You might also return
C<true> but I<not> override the member function to indicate that standard file treatment
(C<EINVAL> for many routines) is OK.
The member function will always be called immediately after the C<Yours()> function, so
you may want to pre-parse the file name in the C<Yours()> function and keep the information
for the member function.